<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>吉他指板训练器</title>
    <!-- 添加吉他图标作为 favicon -->
    <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M85 20c0-8.28-6.72-15-15-15-3.86 0-7.36 1.7-9.8 4.2L40 20 35 15 25 25l5 5-5 5 10 10-5 5 5 5 10-10 5 5-5 5 5 5 10-10 5 5-5 5 5 5c8.28 0 15-6.72 15-15V20zM30 40c-5.52 0-10-4.48-10-10s4.48-10 10-10 10 4.48 10 10-4.48 10-10 10z' fill='%234169e1'/></svg>">
    <style>
        body {
            font-family: "Microsoft YaHei", sans-serif;
            background-color: #f8f9fa;
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .header-container {
            width: 100%;
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        h1 {
            color: #4169e1;
            font-size: calc(1.5rem + 1vw);
            margin: 0;
        }

        .timer-display {
            font-size: calc(1.1rem + 0.5vw);
            color: #4169e1;
            margin: 0;
        }

        .question-number {
            font-size: calc(1.2rem + 0.5vw);
            font-weight: bold;
            color: #4169e1;
            margin-bottom: 10px;
        }

        .question {
            font-size: calc(1.3rem + 0.7vw);
            font-weight: bold;
            color: #4169e1;
            margin-bottom: 10px;
        }

        .selected-note {
            font-size: calc(1.2rem + 0.6vw);
            font-weight: bold;
            color: #4169e1;
            margin-bottom: 20px;
        }

        .note-buttons {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 8px;
            margin-bottom: 20px;
        }

        /* 立体感音符按钮 */
        .note-button {
            background: linear-gradient(to bottom, #4169e1 0%, #345bcc 100%);
            color: white;
            border: none;
            border-radius: 6px;
            padding: 15px 20px;
            font-size: calc(1rem + 0.4vw);
            cursor: pointer;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1);
            transition: all 0.2s ease;
        }

        .note-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15), 0 3px 6px rgba(0, 0, 0, 0.1);
        }

        .note-button:active {
            transform: translateY(1px);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1);
        }

        .control-buttons {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 20px;
        }

        /* 立体感控制按钮 */
        .control-button {
            background: linear-gradient(to bottom, #4169e1 0%, #345bcc 100%);
            color: white;
            border: none;
            border-radius: 6px;
            padding: 10px 15px;
            font-size: calc(0.9rem + 0.3vw);
            cursor: pointer;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1);
            transition: all 0.2s ease;
        }

        .control-button:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15), 0 3px 6px rgba(0, 0, 0, 0.1);
        }

        .control-button:active {
            transform: translateY(1px);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1);
        }

        .note-type-select {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 10px;
            margin-bottom: 20px;
        }

        select {
            padding: 5px 10px;
            font-size: calc(0.9rem + 0.3vw);
        }

        .timer-option {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 10px;
            margin-bottom: 20px;
        }

        .result {
            font-size: calc(1.1rem + 0.5vw);
            margin-top: 20px;
            margin-bottom: 10px;
        }

        .stats {
            font-size: calc(0.9rem + 0.3vw);
            color: #4169e1;
        }

        /* 新增样式，用于分组显示音符按钮 */
        .note-group {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            gap: 8px;
            margin-bottom: 8px;
        }

        .group-label {
            width: 100%;
            text-align: center;
            font-weight: bold;
            margin-bottom: 5px;
        }

        /* 倒计时显示样式 */
        .countdown-display {
            font-size: calc(0.9rem + 0.3vw);
            color: #4169e1;
            margin-left: 10px;
        }

        /* 开始按钮活动状态样式 */
        .control-button.active {
            background: linear-gradient(to bottom, #ff8c00 0%, #ff7f00 100%);
        }
    </style>
</head>

<body>
    <div class="header-container">
        <div class="timer-display" id="result1">测试：</div>
		<div class="timer-display" id="result"></div>
    </div>
    <div class="question-number" id="questionNumber">第 0 题</div>
    <div class="question" id="question"></div>
    <div class="selected-note" id="selectedNote">你选择的: </div>
    <div class="note-buttons" id="noteButtons"></div>
    <div class="control-buttons">
        <button class="control-button" id="startStopButton">开始</button>
        <button class="control-button" id="nextButton" disabled>下一题</button>
    </div>
    <div class="note-type-select">
        <label for="noteType">练习类型:</label>
        <select id="noteType">
            <option>自然音</option>
            <option>升号音</option>
            <option>降号音</option>
            <option>所有音</option>
        </select>
    </div>
    <div class="timer-option">
        <input type="checkbox" id="timerCheckbox">
        <label for="timerCheckbox">启用计时</label>
        <label for="questionTimeSelect">计时时间:</label>
        <select id="questionTimeSelect">
            <option value="5">5 秒</option>
            <option value="10">10 秒</option>
            <option value="15">15 秒</option>
            <option value="20">20 秒</option>
        </select>
        <span class="countdown-display" id="countdownDisplay"></span>
    </div>
    <div class="stats" id="stats">正确: 0 题, 错误: 0 题, 正确率: 0%</div>
	<div class="timer-display" id="timerDisplay">用时: 00:00:00</div>

    <script>
        const questionNumberLabel = document.getElementById('questionNumber');
        const questionLabel = document.getElementById('question');
        const resultLabel = document.getElementById('result');
        const selectedNoteLabel = document.getElementById('selectedNote');
        const noteButtonsDiv = document.getElementById('noteButtons');
        const startStopButton = document.getElementById('startStopButton');
        const nextButton = document.getElementById('nextButton');
        const noteTypeComboBox = document.getElementById('noteType');
        const timerCheckBox = document.getElementById('timerCheckbox');
        const statsLabel = document.getElementById('stats');
        const timerDisplay = document.getElementById('timerDisplay');
        const countdownDisplay = document.getElementById('countdownDisplay');
        const questionTimeSelect = document.getElementById('questionTimeSelect');

        let questionTimer;
        let currentString, currentFret;
        let notesMap = {};
        let questionTime = 5;
        let questionActive = false;
        let timeExpired = false;
        let selectedNote = '';
        let noteButtons = [];
        let correctAnswer = '';
        let useTimer = false;
        let questionCount = 0;
        let correctCount = 0;
        let wrongCount = 0;
        let isTrainingActive = false;
        let answerCorrect = false;
        let totalTime = 0; // 总计时时间
        let timerInterval; // 计时定时器
        let lastNoteType = noteTypeComboBox.value; // 记录上次选择的练习类型

        // 音符等价映射表
        const noteEquivalents = {
            "C#": ["Db"],
            "Db": ["C#"],
            "D#": ["Eb"],
            "Eb": ["D#"],
            "F#": ["Gb"],
            "Gb": ["F#"],
            "G#": ["Ab"],
            "Ab": ["G#"],
            "A#": ["Bb"],
            "Bb": ["A#"]
        };

        function initNotesMap() {
            const notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
            for (let i = 0; i <= 12; i++) {
                notesMap[600 + i] = notes[(4 + i) % 12];
                notesMap[500 + i] = notes[(9 + i) % 12];
                notesMap[400 + i] = notes[(2 + i) % 12];
                notesMap[300 + i] = notes[(7 + i) % 12];
                notesMap[200 + i] = notes[(11 + i) % 12];
                notesMap[100 + i] = notes[(4 + i) % 12];
            }
        }

        function createNoteButtons() {
            const naturalNotes = ["C", "D", "E", "F", "G", "A", "B"];
            const sharpNotes = ["C#", "D#", "F#", "G#", "A#"];
            const flatNotes = ["Db", "Eb", "Gb", "Ab", "Bb"];

            // 创建自然音按钮组
            const naturalGroup = document.createElement('div');
            naturalGroup.classList.add('note-group');
            naturalGroup.id = 'naturalGroup';

            const naturalLabel = document.createElement('div');
            naturalLabel.classList.add('group-label');
            naturalLabel.textContent = '自然音';
            naturalGroup.appendChild(naturalLabel);

            naturalNotes.forEach(note => {
                const button = document.createElement('button');
                button.classList.add('note-button');
                button.textContent = note;
                button.addEventListener('click', () => {
                    if (questionActive) {
                        selectNote(note);
                        if (useTimer) {
                            clearInterval(questionTimer);
                        }
                        checkAnswer();
                    }
                });
                naturalGroup.appendChild(button);
                noteButtons.push(button);
            });

            // 创建升号音按钮组
            const sharpGroup = document.createElement('div');
            sharpGroup.classList.add('note-group');
            sharpGroup.id = 'sharpGroup';

            const sharpLabel = document.createElement('div');
            sharpLabel.classList.add('group-label');
            sharpLabel.textContent = '升号音';
            sharpGroup.appendChild(sharpLabel);

            sharpNotes.forEach(note => {
                const button = document.createElement('button');
                button.classList.add('note-button');
                button.textContent = note;
                button.addEventListener('click', () => {
                    if (questionActive) {
                        selectNote(note);
                        if (useTimer) {
                            clearInterval(questionTimer);
                        }
                        checkAnswer();
                    }
                });
                sharpGroup.appendChild(button);
                noteButtons.push(button);
            });

            // 创建降号音按钮组
            const flatGroup = document.createElement('div');
            flatGroup.classList.add('note-group');
            flatGroup.id = 'flatGroup';

            const flatLabel = document.createElement('div');
            flatLabel.classList.add('group-label');
            flatLabel.textContent = '降号音';
            flatGroup.appendChild(flatLabel);

            flatNotes.forEach(note => {
                const button = document.createElement('button');
                button.classList.add('note-button');
                button.textContent = note;
                button.addEventListener('click', () => {
                    if (questionActive) {
                        selectNote(note);
                        if (useTimer) {
                            clearInterval(questionTimer);
                        }
                        checkAnswer();
                    }
                });
                flatGroup.appendChild(button);
                noteButtons.push(button);
            });

            // 添加所有组到容器
            noteButtonsDiv.appendChild(naturalGroup);
            noteButtonsDiv.appendChild(sharpGroup);
            noteButtonsDiv.appendChild(flatGroup);
        }

        function selectNote(note) {
            if (!questionActive) return;
            selectedNote = note;
            selectedNoteLabel.textContent = `你选择的是: ${selectedNote}`;

            // 重置所有按钮样式
            noteButtons.forEach(btn => {
                btn.style.backgroundColor = '';
                btn.style.boxShadow = '';
                btn.style.transform = '';
                btn.style.background = 'linear-gradient(to bottom, #4169e1 0%, #345bcc 100%)';
            });

            // 设置选中按钮的样式
            const selectedBtn = noteButtons.find(btn => btn.textContent === note);
            if (selectedBtn) {
                selectedBtn.style.background = 'linear-gradient(to bottom, #ff8c00 0%, #ff7f00 100%)';
                selectedBtn.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1)';
                selectedBtn.style.transform = 'translateY(1px)';
            }
        }

        function generateQuestion() {
            const selectedNoteType = noteTypeComboBox.value;
            let validPositions = [];

            // 根据选择的音符类型过滤有效的位置
            for (let string = 1; string <= 6; string++) {
                for (let fret = 0; fret <= 12; fret++) {
                    const note = notesMap[string * 100 + fret];
                    if (selectedNoteType === '自然音' && !note.includes('#') && !note.includes('b')) {
                        validPositions.push({ string, fret });
                    } else if (selectedNoteType === '升号音' && note.includes('#')) {
                        validPositions.push({ string, fret });
                    } else if (selectedNoteType === '降号音' && note.includes('b')) {
                        // 这里需要手动映射降号音符
                        const flatToSharpMap = {
                            "Db": "C#",
                            "Eb": "D#",
                            "Gb": "F#",
                            "Ab": "G#",
                            "Bb": "A#"
                        };
                        const sharpEquivalent = flatToSharpMap[note];
                        if (sharpEquivalent === note) {
                            validPositions.push({ string, fret });
                        }
                    } else if (selectedNoteType === '所有音') {
                        // 所有音类型包含所有音符
                        validPositions.push({ string, fret });
                    }
                }
            }

            if (validPositions.length === 0) {
                questionLabel.textContent = '没有符合条件的音符，请选择其他类型';
                return;
            }

            const randomPosition = validPositions[Math.floor(Math.random() * validPositions.length)];
            currentString = randomPosition.string;
            currentFret = randomPosition.fret;
            correctAnswer = notesMap[currentString * 100 + currentFret];

            // 如果是降号音练习，将正确答案转换为降号表示
            if (selectedNoteType === '降号音') {
                const sharpToFlatMap = {
                    "C#": "Db",
                    "D#": "Eb",
                    "F#": "Gb",
                    "G#": "Ab",
                    "A#": "Bb"
                };
                correctAnswer = sharpToFlatMap[correctAnswer] || correctAnswer;
            }

            questionLabel.textContent = `第 ${currentString} 弦 第 ${currentFret} 品 是什么音？`;
            resultLabel.textContent = '';
            selectedNote = '';
            selectedNoteLabel.textContent = '你选择的: ';

            // 重置所有按钮样式
            noteButtons.forEach(btn => {
                btn.style.backgroundColor = '';
                btn.style.boxShadow = '';
                btn.style.transform = '';
                btn.style.background = 'linear-gradient(to bottom, #4169e1 0%, #345bcc 100%)';
            });

            questionCount++;
            questionNumberLabel.textContent = `第 ${questionCount} 题`;
            questionActive = true;
            answerCorrect = false;
            nextButton.disabled = true;

            questionTime = parseInt(questionTimeSelect.value);
            if (useTimer) {
                startQuestionTimer();
            } else {
                countdownDisplay.textContent = '';
            }
        }

        function startQuestionTimer() {
            let secondsLeft = questionTime;
            countdownDisplay.textContent = `倒计时: ${secondsLeft} 秒`;

            questionTimer = setInterval(() => {
                secondsLeft--;
                if (secondsLeft >= 0) {
                    countdownDisplay.textContent = `倒计时: ${secondsLeft} 秒`;
                }

                if (secondsLeft <= 0) {
                    clearInterval(questionTimer);
                    timeExpired = true;
                    checkAnswer();
                }
            }, 1000);
        }

        function checkAnswer() {
            // 检查选择的音符是否正确，考虑等价音符
            let isCorrect = selectedNote === correctAnswer;

            // 如果选择的音符与正确答案不直接相等，检查等价音符
            if (!isCorrect && noteEquivalents[correctAnswer]) {
                isCorrect = noteEquivalents[correctAnswer].includes(selectedNote);
            }

            answerCorrect = isCorrect;

            if (isCorrect) {
                resultLabel.textContent = '回答正确！';
                resultLabel.style.color = 'green';
                correctCount++;

                // 回答正确后自动下一题
                setTimeout(() => {
                    generateQuestion();
                }, 1000);
            } else {
                resultLabel.textContent = `回答错误，正确答案是: ${correctAnswer}`;
                resultLabel.style.color = 'red';
                wrongCount++;

                // 回答错误后禁用音符按钮，启用下一题按钮
                questionActive = false;
                nextButton.disabled = false;
                if (useTimer) {
                    clearInterval(questionTimer);
                    countdownDisplay.textContent = '';
                }
            }

            updateStats();
        }

        function updateStats() {
            const accuracy = correctCount / questionCount * 100 || 0;
            statsLabel.textContent = `正确: ${correctCount} 题, 错误: ${wrongCount} 题, 正确率: ${accuracy.toFixed(2)}%`;
        }

        function updateButtonVisibility() {
            const selectedNoteType = noteTypeComboBox.value;
            const naturalGroup = document.getElementById('naturalGroup');
            const sharpGroup = document.getElementById('sharpGroup');
            const flatGroup = document.getElementById('flatGroup');

            // 重置所有按钮的显示状态
            noteButtons.forEach(btn => {
                btn.style.display = 'none';
            });

            if (selectedNoteType === '自然音') {
                // 只显示自然音组
                naturalGroup.style.display = 'flex';
                sharpGroup.style.display = 'none';
                flatGroup.style.display = 'none';

                // 显示自然音按钮
                naturalGroup.querySelectorAll('.note-button').forEach(btn => {
                    btn.style.display = 'block';
                });
            } else if (selectedNoteType === '升号音') {
                // 只显示升号音组
                naturalGroup.style.display = 'none';
                sharpGroup.style.display = 'flex';
                flatGroup.style.display = 'none';

                // 显示升号音按钮
                sharpGroup.querySelectorAll('.note-button').forEach(btn => {
                    btn.style.display = 'block';
                });
            } else if (selectedNoteType === '降号音') {
                // 只显示降号音组
                naturalGroup.style.display = 'none';
                sharpGroup.style.display = 'none';
                flatGroup.style.display = 'flex';

                // 显示降号音按钮
                flatGroup.querySelectorAll('.note-button').forEach(btn => {
                    btn.style.display = 'block';
                });
            } else if (selectedNoteType === '所有音') {
                // 显示所有组
                naturalGroup.style.display = 'flex';
                sharpGroup.style.display = 'flex';
                flatGroup.style.display = 'flex';

                // 显示所有按钮
                noteButtons.forEach(btn => {
                    btn.style.display = 'block';
                });
            }

            // 切换练习类型时，重新开始计时
            if (selectedNoteType !== lastNoteType) {
                totalTime = 0;
                timerDisplay.textContent = `用时: 00:00:00`;
                if (isTrainingActive) {
                    clearInterval(timerInterval);
                    clearInterval(questionTimer);
                    startTotalTimer();
                    generateQuestion();
                }
            }
            lastNoteType = selectedNoteType;
        }

        function toggleTraining() {
            if (!isTrainingActive) {
                // 开始训练
                isTrainingActive = true;
                startStopButton.textContent = '停止';
                nextButton.disabled = false;
                //startStopButton.classList.add('active'); // 添加活动状态样式

                generateQuestion();
                useTimer = timerCheckBox.checked;
                startTotalTimer();
            } else {
                // 停止训练
                isTrainingActive = false;
                startStopButton.textContent = '开始';
                nextButton.disabled = true;
                //startStopButton.classList.remove('active'); // 移除活动状态样式

                // 停止计时器
                clearInterval(questionTimer);
                clearInterval(timerInterval);
                countdownDisplay.textContent = '';

                questionActive = false;
                questionLabel.textContent = '';
                resultLabel.textContent = '';
                selectedNote = '';
                selectedNoteLabel.textContent = '你选择的: ';

                // 重置所有按钮样式
                noteButtons.forEach(btn => {
                    btn.style.backgroundColor = '';
                    btn.style.boxShadow = '';
                    btn.style.transform = '';
                    btn.style.background = 'linear-gradient(to bottom, #4169e1 0%, #345bcc 100%)';
                });

                // 更新最终统计信息
                updateStats();
            }
        }

        function nextQuestion() {
            if (!isTrainingActive) return;

            // 如果是回答错误后手动下一题
            if (!answerCorrect) {
                generateQuestion();
            }
        }

        function startTotalTimer() {
            timerInterval = setInterval(() => {
                totalTime++;
                const hours = Math.floor(totalTime / 3600).toString().padStart(2, '0');
                const minutes = Math.floor((totalTime % 3600) / 60).toString().padStart(2, '0');
                const seconds = (totalTime % 60).toString().padStart(2, '0');
                timerDisplay.textContent = `用时: ${hours}:${minutes}:${seconds}`;
            }, 1000);
        }

        startStopButton.addEventListener('click', toggleTraining);
        nextButton.addEventListener('click', nextQuestion);

        noteTypeComboBox.addEventListener('change', updateButtonVisibility);

        timerCheckBox.addEventListener('change', () => {
            useTimer = timerCheckBox.checked;
            if (useTimer && questionActive) {
                // 开启计时时，如果当前有活动问题，开始计时
                clearInterval(questionTimer);
                startQuestionTimer();
            } else {
                clearInterval(questionTimer);
                countdownDisplay.textContent = '';
            }
        });

        questionTimeSelect.addEventListener('change', () => {
            questionTime = parseInt(questionTimeSelect.value);
            if (useTimer && questionActive) {
                clearInterval(questionTimer);
                startQuestionTimer();
            }
        });

        initNotesMap();
        createNoteButtons();
        updateButtonVisibility();
    </script>
</body>

</html>